package Web;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TCPServer {
    private static final int PORT = 8888;  // 监听的端口号
    private static final int THREAD_POOL_SIZE = 10;  // 线程池大小

    private ExecutorService executorService;

    public TCPServer() {
        // 创建线程池
        executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
    }

    public void startServer() {

        // 使用ServerSocket监听指定端口
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("服务器已启动，正在监听端口 " + PORT + "......");
            // 当有客户端连接时，通过accept()方法获取Socket对象，并将处理客户端请求的任务提交给线程池
            while (true) {
                // 接收客户端连接，该方法会阻塞直到有客户端连接过来
                Socket clientSocket = serverSocket.accept();
                System.out.println("接收到来自 " + clientSocket.getInetAddress() + " 的连接");

                // ClientHandler实现了Runnable接口，它的run方法包含了具体处理客户端连接的逻辑，如读写数据等操作
                // 将客户端连接处理任务提交给线程池：调用executorService.submit()方法，将一个ClientHandler实例作为任务提交给线程池
                executorService.submit(new ClientHandler(clientSocket));

                // 线程池在接收到提交的任务（ClientHandler实例）后，会在线程池内部的某个线程中调用该任务的run方法。具体来说：
                //● 如果线程池中有空闲的线程，那么会立即使用这个空闲线程来执行ClientHandler的run方法。
                //● 如果线程池中的所有线程都处于忙碌状态，并且任务队列未满，那么提交的任务会被放入任务队列中等待直到空闲，调用其run方法来执行

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // ClientHandler类实现了Runnable接口，用于处理每个客户端的读写操作
    private static class ClientHandler implements Runnable {
        private Socket clientSocket;

        public ClientHandler(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }


        // 在ClientHandler的run方法中，读取客户端发送的数据，然后向客户端发送响应数据，并使用flush()方法确保数据立即发送到网络
        // ClientHandler类的run方法是通过线程池中的线程来调用执行的
        @Override
        public void run() {
            try (InputStream inputStream = clientSocket.getInputStream();
                 OutputStream outputStream = clientSocket.getOutputStream()) {
                byte[] buffer = new byte[1024];
                int length;
                // 读取客户端发送的数据
                while ((length = inputStream.read(buffer)) != -1) {
                    String receivedData = new String(buffer, 0, length);
                    System.out.println("接收到客户端数据: " + receivedData);
                    // 向客户端发送响应数据
                    String response = "你发送的内容是: " + receivedData;
                    outputStream.write(response.getBytes());
                    // 强制将缓冲区数据输出到网络
                    outputStream.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (clientSocket != null) {
                        clientSocket.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        TCPServer server = new TCPServer();
        server.startServer();
    }
}
